package utils

import (
	"bufio"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/axgle/mahonia"
	"golang.org/x/net/html/charset"
	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/unicode"
	"golang.org/x/text/transform"
	"io"
	"log"
	"math"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/gofrs/uuid"
	"github.com/jinzhu/now"
)

func GetNumByStr(s string) int {
	re := regexp.MustCompile("\\d+")
	allString := re.FindAllString(s, 1)
	if len(allString) > 0 {
		num, _ := strconv.Atoi(re.FindAllString(s, 1)[0])
		return num
	}
	return 0
}

func GetUUID() string {
	uid := uuid.Must(uuid.NewV4())
	return uid.String()
}

func CalculateTotalPage(totalCount, pageSize float64) int {
	totalPage := float64(totalCount) / float64(pageSize)

	return int(math.Ceil(totalPage))
}

func MustDateToUnix(date string) int64 {
	if date == `` || date == `0000-00-00` {
		return 0
	}

	loc, _ := time.LoadLocation("Asia/Chongqing")
	t, err := now.ParseInLocation(loc, date)
	if err != nil {
		return 0
	}

	return t.Unix()
}

func GetCurrentDirectory() string {
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}
	return dir //strings.Replace(dir, "\\", "/", -1)			C:\Users\Administrator\AppData\Local\Temp
}

func ConvertToString(src string, srcCode string, tagCode string) string {
	srcCoder := mahonia.NewDecoder(srcCode)
	srcResult := srcCoder.ConvertString(src)
	tagCoder := mahonia.NewDecoder(tagCode)
	_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
	result := string(cdata)
	return result
}

func GetTimeStamp() string {
	msec := time.Now().UnixNano() / 1e9
	return strconv.FormatInt(msec, 10) //时间戳
}

/*
* 数组是否包含指定元素
 */
func IsContain(items []int, item int) bool {
	for _, eachItem := range items {
		if eachItem == item {
			return true
		}
	}
	return false
}

//判断文件或文件夹是否存在
func isExist(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsExist(err) {
			return true
		}
		if os.IsNotExist(err) {
			return false
		}
		fmt.Println(err)
		return false

	}
	return true
}

func Request(url string) (*http.Response, error) {
	client := &http.Client{}
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Fatal(err)
	}
	request.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36")
	response, err := client.Do(request)
	return response, err
}

func DoRequest(url string) (error, *goquery.Document) {
	client := &http.Client{}
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Fatal(err)
	}
	request.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36")
	response, err := client.Do(request)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	if response.StatusCode != 200 {
		log.Fatal("请求失败", response.StatusCode)
	} else {
		log.Println(response.StatusCode)
	}

	bodyReader := bufio.NewReader(response.Body) // 包装下
	rand.Seed(time.Now().UnixNano())
	/*newBodyReader := bodyReader
	saveFile(newBodyReader, strconv.Itoa(rand.Int())+".html")*/
	e := DetermineEncoding(bodyReader)
	utf8Reader := transform.NewReader(bodyReader, e.NewDecoder())
	doc, err := goquery.NewDocumentFromReader(utf8Reader)
	return err, doc
}

func DetermineEncoding(r *bufio.Reader) encoding.Encoding {
	bytes, e := bufio.NewReader(r).Peek(1024)
	if e != nil {
		log.Printf("Fetcher error: %v", e)
		return unicode.UTF8
	}
	e2, _, _ := charset.DetermineEncoding(bytes, "")
	return e2
}

func DeleteExtraSpace(s string) string {
	//删除字符串中的多余空格，有多个空格时，仅保留一个空格
	s1 := strings.Replace(s, "	", " ", -1)       //替换tab为空格
	regstr := "\\s{2,}"                          //两个及两个以上空格的正则表达式
	reg, _ := regexp.Compile(regstr)             //编译正则表达式
	s2 := make([]byte, len(s1))                  //定义字符数组切片
	copy(s2, s1)                                 //将字符串复制到切片
	spc_index := reg.FindStringIndex(string(s2)) //在字符串中搜索
	for len(spc_index) > 0 {                     //找到适配项
		s2 = append(s2[:spc_index[0]+1], s2[spc_index[1]:]...) //删除多余空格
		spc_index = reg.FindStringIndex(string(s2))            //继续在字符串中搜索
	}
	return string(s2)
}

func DownloadHtml(url, filename string) {
	resp, err := Request(url)
	if resp.StatusCode == 200 {
		SaveFile(resp.Body, filename)
	} else {
		panic(err)
	}
}

func SaveFile(rd io.Reader, filename string) {
	reader := bufio.NewReader(rd)
	file, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	// 获得文件的writer对象
	writer := bufio.NewWriter(file)

	written, err := io.Copy(writer, reader)
	if err != nil {
		panic(err)
	}
	log.Printf("Total length1: %d", written)
}
